/*
 * Copyright (c) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "ov12870_cmos.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/mman.h>
#include <memory.h>

#ifdef HI_GPIO_I2C
#include "gpioi2c_ex.h"
#else
#include "hi_i2c.h"
#endif

static int g_fd[ISP_MAX_PIPE_NUM] = {[0 ... (ISP_MAX_PIPE_NUM - 1)] = -1};
static HI_BOOL g_bStandby[ISP_MAX_PIPE_NUM] = {0};

#ifndef NA
#define NA 0xFFFF
#endif
#define I2C_DEV_FILE_NUM     16
#define I2C_BUF_NUM          8
int ov12870_i2c_init(VI_PIPE vi_pipe)
{
    int ret;
    HI_U8 u8DevNum;
    char acDevFile[I2C_DEV_FILE_NUM];
    ISP_SNS_COMMBUS_U *ov12870businfo = HI_NULL;

    ov12870businfo = ov12870_get_bus_Info(vi_pipe);
    if (g_fd[vi_pipe] >= 0) {
        return HI_SUCCESS;
    }
    u8DevNum = ov12870businfo->s8I2cDev;
    ret = snprintf_s(acDevFile, sizeof(acDevFile), sizeof(acDevFile) - 1, "/dev/i2c-%u", u8DevNum);
    if (ret < 0) {
        return HI_FAILURE;
    }
    g_fd[vi_pipe] = open(acDevFile, O_RDWR, S_IRUSR | S_IWUSR);
    if (g_fd[vi_pipe] < 0) {
        SNS_ERR_TRACE("Open /dev/hi_i2c_drv-%u error!\n", u8DevNum);
        return HI_FAILURE;
    }

    ret = ioctl(g_fd[vi_pipe], I2C_SLAVE_FORCE, (OV12870_I2C_ADDR >> 1));
    if (ret < 0) {
        SNS_ERR_TRACE("I2C_SLAVE_FORCE error!\n");
        close(g_fd[vi_pipe]);
        g_fd[vi_pipe] = -1;
        return ret;
    }
    return HI_SUCCESS;
}

int ov12870_i2c_exit(VI_PIPE vi_pipe)
{
    if (g_fd[vi_pipe] >= 0) {
        close(g_fd[vi_pipe]);
        g_fd[vi_pipe] = -1;
        return HI_SUCCESS;
    }
    return HI_FAILURE;
}

int ov12870_read_register(VI_PIPE vi_pipe, HI_U32 addr)
{
    hi_unused(vi_pipe);
    hi_unused(addr);

    return HI_SUCCESS;
}

int ov12870_write_register(VI_PIPE vi_pipe, HI_U32 addr, HI_U32 data)
{
    HI_U32 idx = 0;
    HI_S32 ret;
    HI_U8 buf[I2C_BUF_NUM];

    if (g_fd[vi_pipe] < 0) {
        return HI_SUCCESS;
    }

    if (OV12870_ADDR_BYTE == 2) {  /* 2 byte */
        buf[idx] = (addr >> 8) & 0xff;  /* shift 8 */
        idx++;
        buf[idx] = addr & 0xff;
        idx++;
    } else {
        buf[idx] = addr & 0xff;
        idx++;
    }

    if (OV12870_DATA_BYTE == 2) {  /* 2 byte */
        buf[idx] = (data >> 8) & 0xff;  /* shift 8 */
        idx++;
        buf[idx] = data & 0xff;
        idx++;
    } else {
        buf[idx] = data & 0xff;
        idx++;
    }

    ret = write(g_fd[vi_pipe], buf, (OV12870_ADDR_BYTE + OV12870_DATA_BYTE));
    if (ret < 0) {
        SNS_ERR_TRACE("I2C_WRITE DATA error!\n");
        return HI_FAILURE;
    }
    return HI_SUCCESS;
}

void ov12870_standby(VI_PIPE vi_pipe)
{
    HI_S32 ret;
    ret = ov12870_write_register(vi_pipe, 0x100, 0x00);
    if (ret != HI_SUCCESS) {
        SNS_ERR_TRACE("write register failed!\n");
        return;
    }
    g_bStandby[vi_pipe] = HI_TRUE;
    return;
}

void ov12870_restart(VI_PIPE vi_pipe)
{
    HI_S32 ret;
    ret = ov12870_write_register(vi_pipe, 0x100, 0x01);
    if (ret != HI_SUCCESS) {
        SNS_ERR_TRACE("write register failed!\n");
        return;
    }
    g_bStandby[vi_pipe] = HI_FALSE;
    return;
}

void ov12870_mirror_flip(VI_PIPE vi_pipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip)
{
    HI_U8 u8ImgMode;
    HI_U8 u8BitMask;
    ISP_SNS_STATE_S *sns_state = HI_NULL;

    sns_state = ov12870_get_ctx(vi_pipe);
    u8ImgMode = sns_state->u8ImgMode;

    if ((u8ImgMode == OV12870_8M_30FPS_10BIT_LINEAR_MODE) ||
        (u8ImgMode == OV12870_12M_30FPS_10BIT_LINEAR_MODE)) {
        u8BitMask = 0xFE;
    } else {
        u8BitMask = 0xFF;
    }
    switch (eSnsMirrorFlip) {
        default:
        case ISP_SNS_NORMAL:
            ov12870_write_register(vi_pipe, 0x3821, (0x5 & u8BitMask));
            ov12870_write_register(vi_pipe, 0x3820, 0x0);
            break;
        case ISP_SNS_MIRROR:
            ov12870_write_register(vi_pipe, 0x3821, (0x1 & u8BitMask));
            ov12870_write_register(vi_pipe, 0x3820, 0x0);
            break;
        case ISP_SNS_FLIP:
            ov12870_write_register(vi_pipe, 0x3821, (0x5 & u8BitMask));
            ov12870_write_register(vi_pipe, 0x3820, 0x4);
            break;
        case ISP_SNS_MIRROR_FLIP:
            ov12870_write_register(vi_pipe, 0x3821, (0x1 & u8BitMask));
            ov12870_write_register(vi_pipe, 0x3820, 0x4);
            break;
    }
    return;
}

#define OV12870_SENSOR_FCG_SEQ_COMM_COL    2
static const HI_U16 g_au16SensorCfgSeqComm[][OV12870_SENSOR_FCG_SEQ_COMM_COL] = {
    {0x00, 0x301e},
    {0x01, 0x0103},
    {0xf8, 0x0300},
    {0xf8, 0x0300},
    {0xf8, 0x0300},
    {0xf8, 0x0300},
    {0x00, 0x0303},
    {0x15, 0x0304},
    {0x01, 0x031a},
    {0x5a, 0x0316},
    {0x00, 0x0317},
    {0x12, 0x0320},
    {0x11, 0x300d},
    {0xe1, 0x3019},
    {0x16, 0x301b},
    {0xb4, 0x3023},
    {0x0f, 0x3028},
    {0x00, 0x3507},
    {0x04, 0x3508},
    {0x00, 0x3509},
    {0x00, 0x350a},
    {0x01, 0x350b},
    {0x00, 0x350e},
    {0x01, 0x350f},
    {0x04, 0x350c},
    {0x00, 0x350d},
    {0x00, 0x3603},
    {0xd7, 0x3608},
    {0x70, 0x360a},
    {0x0b, 0x360b},
    {0x3a, 0x360c},
    {0x02, 0x360e},
    {0x06, 0x3611},
    {0x12, 0x3612},
    {0x22, 0x3613},
    {0x94, 0x3618},
    {0x83, 0x3619},
    {0x24, 0x361a},
    {0x58, 0x3623},
    {0x83, 0x3624},
    {0x99, 0x3626},
    {0x60, 0x3627},
    {0x84, 0x3628},
    {0x00, 0x3629},
    {0x05, 0x362a},
    {0x00, 0x3632},
    {0x10, 0x3634},
    {0x10, 0x3635},
    {0x10, 0x3636},
    {0xff, 0x3652},
    {0xff, 0x3653},
    {0x40, 0x3662},
    {0xa5, 0x3666},
    {0x10, 0x366a},
    {0x2a, 0x369f},
    {0x64, 0x36a1},
    {0x8c, 0x36a3},
    {0xbc, 0x36a5},
    {0xe0, 0x36a7},
    {0x00, 0x36a8},
    {0xf4, 0x36a9},
    {0x04, 0x36ab},
    {0x04, 0x36ad},
    {0x04, 0x36af},
    {0x88, 0x3689},
    {0x88, 0x368a},
    {0x08, 0x368b},
    {0x54, 0x3702},
    {0x24, 0x3704},
    {0x50, 0x3706},
    {0xce, 0x3709},
    {0xe4, 0x370b},
    {0x40, 0x3712},
    {0x67, 0x3714},
    {0xd2, 0x371b},
    {0x28, 0x373b},
    {0x2a, 0x373d},
    {0xee, 0x3754},
    {0x08, 0x375a},
    {0x54, 0x3764},
    {0x46, 0x3765},
    {0x20, 0x3768},
    {0x10, 0x376a},
    {0x38, 0x3781},
    {0x01, 0x37d9},
    {0x03, 0x37e3},
    {0x20, 0x37f5},
    {0x14, 0x3801},
    {0x0c, 0x3803},
    {0x10, 0x3804},
    {0x8b, 0x3805},
    {0x00, 0x3820},
    {0x88, 0x383c},
    {0x17, 0x3d85},
    {0x6f, 0x3d87},
    {0x6f, 0x3d8c},
    {0x97, 0x3d8d},
    {0x30, 0x3d90},
    {0x00, 0x4015},
    {0x01, 0x401e},
    {0xa0, 0x401f},
    {0x04, 0x4024},
    {0x04, 0x4026},
    {0x21, 0x4056},
    {0x00, 0x401d},
    {0x08, 0x430f},
    {0xfc, 0x430c},
    {0x05, 0x450a},
    {0x22, 0x4642},
    {0x02, 0x4643},
    {0x38, 0x481f},
    {0x0d, 0x4837},
    {0x83, 0x4b05},
    {0x04, 0x4d00},
    {0x30, 0x4d01},
    {0xb7, 0x4d02},
    {0xaf, 0x4d03},
    {0xa9, 0x4d04},
    {0xa7, 0x4d05},
    {0x00, 0x5001},
    {0xfb, 0x5017},
    {0x04, 0x5020},
    {0x10, 0x5281},
    {0x0f, 0x5282},
    {0x37, 0x5283},
    {0xbf, 0x5500},
    {0x4d, 0x5502},
    {0x3f, 0x5506},
    {0x30, 0x5507},
    {0x04, 0x5508},
    {0x0f, 0x5509},
    {0x43, 0x550a},
    {0x4d, 0x5e02},
    {0x3f, 0x5e06},
    {0x30, 0x5e07},
    {0x04, 0x5e08},
    {0x0f, 0x5e09},
    {0x43, 0x5e0a},
    {0x03, 0x3025},
    {0x03, 0x3664},
    {0xf0, 0x3668},
    {0x0e, 0x3669},
    {0x03, 0x3408},
    {0x40, 0x401a},
};


static const HI_U16 g_au16SensorCfgSeq[][OV12870_MODE_BUTT + 1] = {
    {0x00, 0x00, 0x00, 0x00, 0x0100},
    {0x96, 0x96, 0xb4, 0xb4, 0x3016},
    {0x70, 0x70, 0xf0, 0xf0, 0x3018},
    {0x00, 0x04, 0x00, 0x00, 0x3400},
    {0x01, 0x02, 0x0c, 0x0c, 0x340c},
    {0xbe, 0x5e, 0xce, 0xce, 0x340d},
    {0x03, 0x06, 0x0c, 0x0c, 0x3501},
    {0x1c, 0x5e, 0xe1, 0xe1, 0x3502},
    {0x0c, 0x0c, 0x00, 0x00, 0x3600},
    {0x0b, 0x0b, 0x0a, 0x0a, 0x3602},
    {0x8f, 0x8f, 0x88, 0x88, 0x3621},
    {0x98, 0x98, 0x68, 0x68, 0x3622},
    {0x04, 0x04, 0x54, 0x54, 0x366c},
    {0x21, 0x21, 0x20, 0x20, 0x3726},
    {0x05, 0x07, 0x0f, 0x10, 0x3808},
    {0x00, 0x80, 0x00, 0x00, 0x3809},
    {0x02, 0x04, 0x08, 0x0c, 0x380a},
    {0xd0, 0x38, 0x70, 0x00, 0x380b},
    {0x03, 0x03, 0x07, 0x07, 0x380c},
    {0x84, 0x84, 0x08, 0x08, 0x380d},
    {0x03, 0x06, 0x0d, 0x0d, 0x380e},
    {0x40, 0x82, 0x06, 0x06, 0x380f},
    {0x03, 0x03, 0x10, 0x10, 0x3811},
    {0x0c, 0x0c, 0x08, 0x08, 0x3813},
    {0x31, 0x31, 0x11, 0x11, 0x3814},
    {0x31, 0x31, 0x11, 0x11, 0x3815},
    {0x05, 0x05, 0x04, 0x04, 0x3821},
    {0x0f, 0x0f, 0x1f, 0x1f, 0x4016},
    {0x0f, 0x0f, 0x1f, 0x1f, 0x4018},
    {0x00, 0x00, 0x74, 0x74, 0x4021},
    {0x00, 0x00, 0x94, 0x94, 0x4023},
    {0x00, 0x00, 0x88, 0x88, 0x4025},
    {0x00, 0x00, 0xa6, 0xa6, 0x4027},
    {0x86, 0x86, 0xa7, 0xa7, 0x5000},
    {0x20, 0x20, 0x50, 0x50, 0x5045},
    {0x80, 0x80, 0x4f, 0x4f, 0x5047},
    {0x28, 0x28, 0x30, 0x30, 0x5049},
    {0x60, 0x60, 0x2f, 0x2f, 0x504b},
    {0x00, 0x00, 0x01, 0x01, 0x5300},
    {0x06, 0x06, 0x10, 0x10, 0x5360},
    {0x40, 0x40, 0xa0, 0xa0, 0x5361},
    {0x04, 0x04, 0x0c, 0x0c, 0x5362},
    {0xb0, 0xb0, 0x60, 0x60, 0x5363},
    {0x00, 0x00, 0x08, 0x08, 0x5367},
    {0x88, 0x88, 0x50, 0x50, 0x5369},
    {0x00, 0x00, 0x10, 0x10, 0x536a},
    {0x8a, 0x8a, 0x4f, 0x4f, 0x536b},
    {0x03, 0x03, 0x30, 0x30, 0x536d},
    {0x00, 0x00, 0x0c, 0x0c, 0x536e},
    {0x05, 0x05, 0x2f, 0x2f, 0x536f},
    {0x00, 0x00, 0x20, 0x20, 0x5378},
    {0x00, 0x00, 0x20, 0x20, 0x537a},
    {0x00, 0x00, 0x20, 0x20, 0x5388},
    {0x00, 0x00, 0x20, 0x20, 0x538a},
    {0x00, 0x00, 0x20, 0x20, 0x5399},
    {0x00, 0x00, 0x20, 0x20, 0x539b},
    {0x00, 0x00, 0x20, 0x20, 0x53a9},
    {0x00, 0x00, 0x20, 0x20, 0x53ab},
    {0x00, 0x00, 0x20, 0x20, 0x53b8},
    {0x00, 0x00, 0x20, 0x20, 0x53ba},
    {0x00, 0x00, 0x20, 0x20, 0x53c8},
    {0x00, 0x00, 0x20, 0x20, 0x53ca},
    {0x00, 0x00, 0x20, 0x20, 0x53d9},
    {0x00, 0x00, 0x20, 0x20, 0x53db},
    {0x00, 0x00, 0x20, 0x20, 0x53e9},
    {0x00, 0x00, 0x20, 0x20, 0x53eb},
    {0x00, 0x00, 0x20, 0x20, 0x53f4},
    {0x00, 0x00, 0x20, 0x20, 0x53f6},
    {0x00, 0x00, 0x70, 0x70, 0x53f8},
    {0x00, 0x00, 0x70, 0x70, 0x53fa},
    {0x00, 0x00, 0x20, 0x20, 0x53fc},
    {0x00, 0x00, 0x20, 0x20, 0x53fe},
    {0x00, 0x00, 0x20, 0x20, 0x5404},
    {0x00, 0x00, 0x20, 0x20, 0x5406},
    {0x00, 0x00, 0x70, 0x70, 0x5408},
    {0x00, 0x00, 0x70, 0x70, 0x540a},
    {0x00, 0x00, 0x20, 0x20, 0x540c},
    {0x00, 0x00, 0x20, 0x20, 0x540e},
    {0x00, 0x00, 0x20, 0x20, 0x5415},
    {0x00, 0x00, 0x20, 0x20, 0x5417},
    {0x00, 0x00, 0x70, 0x70, 0x5419},
    {0x00, 0x00, 0x70, 0x70, 0x541b},
    {0x00, 0x00, 0x20, 0x20, 0x541d},
    {0x00, 0x00, 0x20, 0x20, 0x541f},
    {0x00, 0x00, 0x20, 0x20, 0x5425},
    {0x00, 0x00, 0x20, 0x20, 0x5427},
    {0x00, 0x00, 0x70, 0x70, 0x5429},
    {0x00, 0x00, 0x70, 0x70, 0x542b},
    {0x00, 0x00, 0x20, 0x20, 0x542d},
    {0x00, 0x00, 0x20, 0x20, 0x542f},
    {0x00, 0x00, 0x20, 0x20, 0x5434},
    {0x00, 0x00, 0x20, 0x20, 0x5436},
    {0x00, 0x00, 0x70, 0x70, 0x5438},
    {0x00, 0x00, 0x70, 0x70, 0x543a},
    {0x00, 0x00, 0x20, 0x20, 0x543c},
    {0x00, 0x00, 0x20, 0x20, 0x543e},
    {0x00, 0x00, 0x20, 0x20, 0x5444},
    {0x00, 0x00, 0x20, 0x20, 0x5446},
    {0x00, 0x00, 0x70, 0x70, 0x5448},
    {0x00, 0x00, 0x70, 0x70, 0x544a},
    {0x00, 0x00, 0x20, 0x20, 0x544c},
    {0x00, 0x00, 0x20, 0x20, 0x544e},
    {0x00, 0x00, 0x20, 0x20, 0x5455},
    {0x00, 0x00, 0x20, 0x20, 0x5457},
    {0x00, 0x00, 0x70, 0x70, 0x5459},
    {0x00, 0x00, 0x70, 0x70, 0x545b},
    {0x00, 0x00, 0x20, 0x20, 0x545d},
    {0x00, 0x00, 0x20, 0x20, 0x545f},
    {0x00, 0x00, 0x20, 0x20, 0x5465},
    {0x00, 0x00, 0x20, 0x20, 0x5467},
    {0x00, 0x00, 0x70, 0x70, 0x5469},
    {0x00, 0x00, 0x70, 0x70, 0x546b},
    {0x00, 0x00, 0x20, 0x20, 0x546d},
    {0x00, 0x00, 0x20, 0x20, 0x546f},
    {0x00, 0x00, 0x18, 0x18, 0x5475},
    {0x00, 0x00, 0x01, 0x01, 0x5700},
    {0x00, 0x00, 0x08, 0x08, 0x57c3},
    {0x88, 0x88, 0x50, 0x50, 0x57c5},
    {0x00, 0x00, 0x10, 0x10, 0x57c6},
    {0x8a, 0x8a, 0x4f, 0x4f, 0x57c7},
    {0x03, 0x03, 0x30, 0x30, 0x57c9},
    {0x00, 0x00, 0x0c, 0x0c, 0x57ca},
    {0x05, 0x05, 0x2f, 0x2f, 0x57cb},
    {0x00, 0x00, 0x20, 0x20, 0x57dc},
    {0x00, 0x00, 0x20, 0x20, 0x57de},
    {0x00, 0x00, 0x20, 0x20, 0x57ec},
    {0x00, 0x00, 0x20, 0x20, 0x57ee},
    {0x00, 0x00, 0x20, 0x20, 0x57fd},
    {0x00, 0x00, 0x20, 0x20, 0x57ff},
    {0x00, 0x00, 0x20, 0x20, 0x580d},
    {0x00, 0x00, 0x20, 0x20, 0x580f},
    {0x00, 0x00, 0x20, 0x20, 0x581c},
    {0x00, 0x00, 0x20, 0x20, 0x581e},
    {0x00, 0x00, 0x20, 0x20, 0x582c},
    {0x00, 0x00, 0x20, 0x20, 0x582e},
    {0x00, 0x00, 0x20, 0x20, 0x583d},
    {0x00, 0x00, 0x20, 0x20, 0x583f},
    {0x00, 0x00, 0x20, 0x20, 0x584d},
    {0x00, 0x00, 0x20, 0x20, 0x584f},
    {0x00, 0x00, 0x08, 0x08, 0x5864},
    {0x00, 0x00, 0x08, 0x08, 0x5868},
    {0x00, 0x00, 0x0c, 0x0c, 0x5884},
    {0x00, 0x00, 0x0c, 0x0c, 0x5888},
    {0x00, 0x00, 0x0c, 0x0c, 0x58a6},
    {0x00, 0x00, 0x0c, 0x0c, 0x58aa},
    {0x00, 0x00, 0x08, 0x08, 0x58c6},
    {0x00, 0x00, 0x08, 0x08, 0x58ca},
    {0x00, 0x00, 0x08, 0x08, 0x58e4},
    {0x00, 0x00, 0x08, 0x08, 0x58e8},
    {0x00, 0x00, 0x0c, 0x0c, 0x5904},
    {0x00, 0x00, 0x0c, 0x0c, 0x5908},
    {0x00, 0x00, 0x0c, 0x0c, 0x5926},
    {0x00, 0x00, 0x0c, 0x0c, 0x592a},
    {0x00, 0x00, 0x08, 0x08, 0x5946},
    {0x00, 0x00, 0x08, 0x08, 0x594a},
    {0x00, 0x00, 0x40, 0x40, 0x5956},
    {0x00, 0x00, 0x10, 0x10, 0x5959},
    {0x00, 0x00, 0x10, 0x10, 0x595b},
    {0x00, 0x00, 0x10, 0x10, 0x595c},
    {0x00, 0x00, 0x80, 0x80, 0x595d},
    {0x00, 0x00, 0x0c, 0x0c, 0x595e},
    {0x00, 0x00, 0x40, 0x40, 0x595f},
    {0x01, 0x01, 0x04, 0x04, 0x5954},
    {0x00, 0x00, 0x01, 0x01, 0x5a90},
    {0x00, 0x00, 0x20, 0x20, 0x5a18},
    {0x00, 0x00, 0x20, 0x20, 0x5a1a},
    {0x00, 0x00, 0x20, 0x20, 0x5a28},
    {0x00, 0x00, 0x20, 0x20, 0x5a2a},
    {0x00, 0x00, 0x20, 0x20, 0x5a39},
    {0x00, 0x00, 0x20, 0x20, 0x5a3b},
    {0x00, 0x00, 0x20, 0x20, 0x5a49},
    {0x00, 0x00, 0x20, 0x20, 0x5a4b},
    {0x00, 0x00, 0x20, 0x20, 0x5a58},
    {0x00, 0x00, 0x20, 0x20, 0x5a5a},
    {0x00, 0x00, 0x20, 0x20, 0x5a68},
    {0x00, 0x00, 0x20, 0x20, 0x5a6a},
    {0x00, 0x00, 0x20, 0x20, 0x5a79},
    {0x00, 0x00, 0x20, 0x20, 0x5a7b},
    {0x00, 0x00, 0x20, 0x20, 0x5a89},
    {0x00, 0x00, 0x20, 0x20, 0x5a8b},
    {0x08, 0x08, 0x00, 0x00, 0x4a00},
};

void ov12870_init(VI_PIPE vi_pipe)
{
    HI_U32 i, u32SeqEntries;
    HI_S32 ret = HI_SUCCESS;
    HI_U8  u16RegData, u8ImgMode;
    HI_U16 u16RegAddr;
    ISP_SNS_STATE_S *pastov12870 = HI_NULL;
    const OV12870_VIDEO_MODE_TBL_S *ov12870modetb1 = HI_NULL;
    pastov12870 = ov12870_get_ctx(vi_pipe);
    HI_BOOL bInit = pastov12870->bInit;
    u8ImgMode = pastov12870->u8ImgMode;
    ov12870modetb1 = ov12870_get_mode_tb1(u8ImgMode);
    if (bInit == HI_FALSE) {
        ov12870_i2c_init(vi_pipe); /* 2. sensor i2c init */
    }
    if (!g_bStandby[vi_pipe] || !pastov12870->bInit) {
        u32SeqEntries = sizeof(g_au16SensorCfgSeqComm) / sizeof(g_au16SensorCfgSeqComm[0]);
        for (i = 0; i < u32SeqEntries; i++) {
            u16RegAddr = g_au16SensorCfgSeqComm[i][1];
            u16RegData = g_au16SensorCfgSeqComm[i][0];
            ov12870_write_register(vi_pipe, u16RegAddr, u16RegData);
        }
    }
    u32SeqEntries = sizeof(g_au16SensorCfgSeq) / sizeof(g_au16SensorCfgSeq[0]);
    for (i = 0; i < u32SeqEntries; i++) {
        u16RegAddr = g_au16SensorCfgSeq[i][OV12870_MODE_BUTT];
        u16RegData = g_au16SensorCfgSeq[i][u8ImgMode];
        ret += ov12870_write_register(vi_pipe, u16RegAddr, u16RegData);
    }
    for (i = 0; i < pastov12870->astRegsInfo[0].u32RegNum; i++) {
        ret += ov12870_write_register(vi_pipe,
                                      pastov12870->astRegsInfo[0].astI2cData[i].u32RegAddr,
                                      pastov12870->astRegsInfo[0].astI2cData[i].u32Data);
    }
    if (ret != HI_SUCCESS) {
        SNS_ERR_TRACE("write register failed!\n");
        return;
    }
    pastov12870->bInit = HI_TRUE;
    ov12870_restart(vi_pipe);
    printf("OV12870 %s init succuss!\n", ov12870modetb1->pszModeName);
    return;
}

void ov12870_exit(VI_PIPE vi_pipe)
{
    HI_S32 ret;
    ret = ov12870_i2c_exit(vi_pipe);
    if (ret != HI_SUCCESS) {
        SNS_ERR_TRACE("i2c exit failed!\n");
        return;
    }
    g_bStandby[vi_pipe] = HI_FALSE;
    return;
}
